import config from '../config'
import Sequelize from 'sequelize'
import bcrypt from 'bcrypt'
import jwt from 'jsonwebtoken'

export function users(sequelize) {
    const indexs = [
        { fields: ['code', 'email', 'mobile', 'password'] }
    ]
    const instanceMethods = {
        /**
         * generate an JWT Token by user.id and user.type
         */
        generateToken: function () {
            let expiresIn = 86400 * 30 // 30天
            let token = jwt.sign({ id: this.id }, config.token, { expiresIn })
            return {
                expiresIn,
                token
            }
        }
    }
    const User = sequelize.define('users', {
        id: {
            type: Sequelize.UUID,
            primaryKey: true,
            defaultValue: Sequelize.UUIDV4,
            allowNull: false
        },
        code: {
            type: Sequelize.STRING,
            allowNull: false, unique: true,
            validate: {
                notEmpty: true,
                isNumeric: true,
                len: [8, 13]
            }
        },
        mobile: {
            type: Sequelize.STRING,
            allowNull: true,
            unique: true,
            validate: {
                isNumeric: true
            }
        },
        email: {
            type: Sequelize.STRING,
            allowNull: true,
            unique: true,
            validate: {
                isEmail: true
            }
        },
        password: {
            type: Sequelize.STRING,
            allowNull: false,
            validate: {
                notEmpty: true
            }
        },
        salt: { type: Sequelize.STRING },
        status: { type: Sequelize.INTEGER, defaultValue: 0, allowNull: false },//0 正常，1 注销
    }, { indexs, instanceMethods })

    async function hookHandler(user, next) {
        if (!user.changed('password')) {
            return
        }
        if (!user.salt) {
            user.salt = await new Promise((resolve, reject) => {
                bcrypt.genSalt(10, (err, salt) => {
                    err ? reject(err) : resolve(salt)
                })
            })
        }
        user.password = await new Promise((resolve, reject) => {
            bcrypt.hash(user.password, user.salt, (err, hash) => {
                err ? reject(err) : resolve(hash)
            })
        })
        return user
    }

    //hash passwordn
    User.addHook('beforeUpdate', hookHandler)
    User.addHook('beforeCreate', hookHandler)

    return User
}
export function tokens(sequelize) {
    const indexs = [
        { fields: ['access_token'] }
    ]
    return sequelize.define('oauth_tokens', {
        id: { type: Sequelize.UUID, primaryKey: true, defaultValue: Sequelize.UUIDV4, allowNull: false },
        accessToken: { type: Sequelize.STRING, allowNull: false },
        accessTokenExpiresOn: { type: Sequelize.DATE, allowNull: false },
        clientId: { type: Sequelize.STRING, allowNull: false },
        refreshToken: { type: Sequelize.STRING, allowNull: false },
        refreshTokenExpiresOn: { type: Sequelize.DATE, allowNull: false },
        userId: { type: Sequelize.UUID, allowNull: false },
    },{indexs})
}
export function clients(sequelize) {
    return sequelize.define('oauth_clients', {
        clientId: { type: Sequelize.STRING, primaryKey: true, allowNull: false },
        clientSecret: { type: Sequelize.STRING, allowNull: false },
        redirectUri: { type: Sequelize.STRING, allowNull: false },

    })
}